﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;
using tester;
using System.Threading;

namespace FontManager
{
    public partial class MainForm : Form
    {
        #region Variables
        /// <summary>
        /// the reason of having it in this class is so that I could access game1 and if needed xnaHelper class.
        /// </summary>
        public Game1 GAME;

        /// <summary>
        /// static font object so I could access it from anywhere.
        /// </summary>
        public static FontFont NEW_FONT;
        /// <summary>
        /// the path of xml file which is loaded
        /// </summary>
        string OLD_DOC_PATH = "";
        /// <summary>
        /// loaded xDocument file from OLD_DOC_PATH
        /// </summary>
        XDocument OLD_DOC;

        /// <summary>
        /// the width of dataGridViewCell
        /// </summary>
        private int CELL_WIDTH = 0; //
        /// <summary>
        /// original cell _image width at 100% used for resizing and showing info
        /// </summary>
        private int CELL_ORIGIN_WIDTH = 0;

        /// <summary>
        /// context menu which will be loaded for dataGridViewCells
        /// </summary>
        private string[] GLYPH_MENU = { "Add...", "Add origin...", "Replace...", "Remove...", "Edit...", "Open in Editor..." };
        /// <summary>
        /// context menu which will be loaded for preview window
        /// </summary>
        private string[] ZOOM_MENU = { "25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%" };
        /// <summary>
        /// tabControl pages context menu
        /// </summary>
        private string[] TAB_MENU = { "25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%", "400%", "Close", "Close All" };
        /// <summary>
        /// I am copying xml files to destination folder so I already know its uri
        /// </summary>
        string DUMMY_SET_URI = @"XML\DummySet.xml";
        Dictionary<string, DummySet> DUMMY_SET = new Dictionary<string, DummySet>();
        string DUMMY_SET_CURRENT = "Default";
        /// <summary>
        /// I am copying xml files to destination folder so I already know its uri
        /// </summary>
        private string FILTER_URI = @"XML\Filters.xml";
        private Dictionary<string, Filter> FILTER_SET = new Dictionary<string, Filter>();
        private string FILTER_SET_CURRENT = "NONE";
        int NUMBER_OF_IMAGES = 0;
        //====================================================================================================================================//
        #endregion

        #region Constructor
        public MainForm()
        {
            InitializeComponent();
            loadFilterXML();
            loadDummyXML();
            initTooltips();
            initContextMenus();

#if DEBUG
            open(@"C:\Users\Min0\Desktop\testFont\newVersion2.xml");
#endif
            comboBoxDummySetsInit();
            comboBoxFilterInit();
        }
        //====================================================================================================================================//
        #endregion
        /// <summary>
        /// self explenatory methods. initializes combo boxes and deals with its changed item events.
        /// </summary>
        #region comboBoxDummySetsInit \ checkBoxDummy_CheckedChanged
        private void comboBoxDummySetsInit()
        {
            comboBoxDummySets.Items.Clear();
            foreach (var c in DUMMY_SET)
                comboBoxDummySets.Items.Add(c.Key);
            comboBoxDummySets.SelectedIndex = comboBoxDummySets.Items.IndexOf("Default");
        }

        private void comboBoxDummySets_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            try
            {
                if (comboBoxDummySets.SelectedItem != null)
                {
                    DUMMY_SET_CURRENT = comboBoxDummySets.SelectedItem.ToString();
                    updateDataGridView(true, true, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void checkBoxDummy_CheckedChanged(object sender, EventArgs e)
        {
            updateDataGridView(true, true, false);
        }
        #endregion

        #region comboBoxFilterInit \ comboBoxFilter_SelectedIndexChanged
        private void comboBoxFilterInit()
        {
            comboBoxFilter.Items.Clear();
            foreach (var c in FILTER_SET)
            {
                comboBoxFilter.Items.Add(c.Key);
            }
            comboBoxFilter.SelectedIndex = comboBoxFilter.Items.IndexOf("NONE");
        }

        private void comboBoxFilter_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (comboBoxFilter.SelectedItem != null)
                {
                    FILTER_SET_CURRENT = comboBoxFilter.SelectedItem.ToString();
                    updateDataGridView(true, true, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        #endregion

        #region DATA GRID VIEW
        //=================================INITIALIZATION=====================================================//
        /// <summary>
        /// on initialization begining changes cursor to waiting.
        /// clears grid view;
        /// checks if dummy is used to determine the number of images (number of cells);
        /// if cell width is 0 sets it to 30 as default
        /// calculates columns per width and column width to know how many shall be;
        /// Takes scroll bar width into consideration to prevent having horizontal scrool bar;
        /// creates a table and load rows and columns;
        /// sets cursor to default.
        /// </summary>
        private void initDataGridView()
        {
            try
            {
                Cursor = Cursors.WaitCursor;

                dataGridViewGlyphs.Rows.Clear();
                dataGridViewGlyphs.Columns.Clear();

                if (DUMMY_SET[DUMMY_SET_CURRENT].Count > 0)
                    NUMBER_OF_IMAGES = DUMMY_SET[DUMMY_SET_CURRENT].Count;
                else
                    NUMBER_OF_IMAGES = NEW_FONT.Characters.Count;

                if (CELL_WIDTH == 0)
                {
                    CELL_WIDTH = 30;
                    CELL_ORIGIN_WIDTH = 30;
                }

                int columnsPerWidth = (dataGridViewGlyphs.Width - (SystemInformation.VerticalScrollBarWidth + 1)) / CELL_WIDTH;
                int numberOfRows = 0;

                numberOfRows = NUMBER_OF_IMAGES / columnsPerWidth;

                // Do we have a an overfill for a row
                if (NUMBER_OF_IMAGES % columnsPerWidth > 0)
                {
                    numberOfRows += 1;
                }

                // Dynamically create the columns
                for (int index = 0; index < columnsPerWidth; index++)
                {
                    CustomDataGridViewImageColumn dataGridViewColumn = new CustomDataGridViewImageColumn();
                    dataGridViewGlyphs.Columns.Add(dataGridViewColumn);
                    dataGridViewGlyphs.Columns[index].Width = CELL_WIDTH;
                }

                // Create the rows
                for (int index = 0; index < numberOfRows; index++)
                {
                    dataGridViewGlyphs.Rows.Add();
                    dataGridViewGlyphs.Rows[index].Height = CELL_WIDTH;
                }
                Cursor = Cursors.Default;
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        //=====================================LOADING=====================================================//
        /// <summary>
        /// check if any filter is used;
        /// based on it loads the characters in the grid view;
        /// if the images is from dummy set loads it to DummyImage value;
        /// sets the image to DummyImage;
        /// </summary>
        private void LoadImagesToGridViewDummy()
        {
            try
            {
                Cursor = Cursors.WaitCursor;
                int columnIndex = 0;
                int rowIndex = 0;
                for (int index = 0; index < DUMMY_SET[DUMMY_SET_CURRENT].Count; index++)
                {
                    if (FILTER_SET_CURRENT == "NONE" || FILTER_SET[FILTER_SET_CURRENT].HexsValueList.Contains(DUMMY_SET[DUMMY_SET_CURRENT].HexsValueList[index]))
                    {
                        Image image = Helper.drawImageFromChar(Helper.HEXtoCHAR(DUMMY_SET[DUMMY_SET_CURRENT].HexsValueList[index]), CELL_WIDTH, CELL_WIDTH);

                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).DummyImage = image;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).DummyImage;

                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).GetCellSource = CustomDataGridViewCell.CellSource.Dummy;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = DUMMY_SET[DUMMY_SET_CURRENT].HexsValueList[index];

                        if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                        {
                            rowIndex += 1;
                            columnIndex = 0;
                        }
                        else
                        {
                            columnIndex++;
                        }
                    }
                }
                Cursor = Cursors.Default;
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// check if any filter is used;
        /// based on it loads the characters in the grid view;
        /// if the images is from dummy set loads it to XmlImage value;
        /// sets the image to XmlImage;
        /// based on checkBoxDummy deals with its load or !load.
        /// </summary>
        private void LoadImagesToGridView()
        {
            try
            {
                Cursor = Cursors.WaitCursor;
                if (checkBoxDummy.Checked)
                {
                    for (int index = 0; index < NEW_FONT.Characters.Count; index++)
                        if (FILTER_SET_CURRENT == "NONE" || FILTER_SET[FILTER_SET_CURRENT].HexsValueList.Contains(NEW_FONT.Characters[index].Name))
                            foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                                foreach (CustomDataGridViewCell cell in row.Cells)
                                    if (cell.ToolTipText == NEW_FONT.Characters[index].Name)
                                    {
                                        if (File.Exists(NEW_FONT.Characters[index].Image))
                                        {
                                            Image image = Helper.ResizeImage(NEW_FONT.Characters[index].Image, CELL_WIDTH, CELL_WIDTH, false);
                                            cell.XmlImage = image;
                                            cell.Value = cell.XmlImage;
                                            cell.GetCellSource = CustomDataGridViewCell.CellSource.XML;
                                        }
                                    }
                }

                if (!checkBoxDummy.Checked)
                {
                    int columnIndex = 0;
                    int rowIndex = 0;
                    for (int index = 0; index < NEW_FONT.Characters.Count; index++)
                    {
                        if (FILTER_SET_CURRENT == "NONE" || FILTER_SET[FILTER_SET_CURRENT].HexsValueList.Contains(NEW_FONT.Characters[index].Name))
                        {
                            LoadImagesToGridViewFont(ref columnIndex, ref rowIndex, index);
                        }
                    }
                }
                Cursor = Cursors.Default;
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void LoadImagesToGridViewFont(ref int columnIndex, ref int rowIndex, int index)
        {
            try
            {
                if (File.Exists(NEW_FONT.Characters[index].Image))
                {
                    Image image = Helper.ResizeImage(NEW_FONT.Characters[index].Image, CELL_WIDTH, CELL_WIDTH, false);

                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).XmlImage = image;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).XmlImage;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = NEW_FONT.Characters[index].Name;
                    //need test
                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as CustomDataGridViewCell).GetCellSource = CustomDataGridViewCell.CellSource.XML;

                    if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                    {
                        rowIndex += 1;
                        columnIndex = 0;
                    }
                    else
                    {
                        columnIndex++;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        //=================================UPDATE=====================================================//
        /// <summary>
        /// deals with datagridview updating.
        /// based on values guesses with, loads images, recreates grid view table;
        /// </summary>
        /// <param Name="initgridview"></param>
        /// <param Name="loadimages"></param>
        /// <param Name="guessWidth"></param>
        private void updateDataGridView(bool initgridview, bool loadimages, bool guessWidth)
        {
            try
            {
                if (guessWidth && NEW_FONT != null)
                {
                    guessImgWidth();
                }

                if (initgridview)
                {
                    initDataGridView();
                }

                if (loadimages)
                {
                    if (checkBoxDummy.Checked)
                    {
                        LoadImagesToGridViewDummy();
                    }

                    if (NEW_FONT != null)
                    {
                        LoadImagesToGridView();
                        refreshList();
                        labelGridScale.Text = Helper.getScale(CELL_ORIGIN_WIDTH, CELL_WIDTH).ToString() + "%";
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        //=================================HELPER METHODS=====================================================//
        /// <summary>
        /// check to determine what is the course of specific cells image
        /// </summary>
        /// <returns></returns>
        private bool cellSourceDummy()
        {
            if ((dataGridViewGlyphs.CurrentCell as CustomDataGridViewCell).GetCellSource == CustomDataGridViewCell.CellSource.Dummy)
                return true;
            else
                return false;
        }

        /// <summary>
        /// guesses the image width using helper.getdefaultWidth method.
        /// </summary>
        private void guessImgWidth()
        {
            if (NEW_FONT != null)
            {
                try
                {
                    //taking a list of characters and making _image width the biggest character;
                    CELL_WIDTH = Helper.getDefaultWidth(NEW_FONT.Characters);
                    CELL_ORIGIN_WIDTH = CELL_WIDTH;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }

        /// <summary>
        /// refreshes the list by sorting it.
        /// </summary>
        private void refreshList()
        {
            if (NEW_FONT != null)
            {
                try
                {
                    Helper.sortCharacterList(NEW_FONT.Characters);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }
        //=================================EVENT LISTENERS=====================================================//
        /// <summary>
        /// handles datagridview enter and delete key pressed events.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                editCharacter();
            }
            if (e.KeyData == Keys.Delete)
            {
                removeCharacter();
            }
        }

        /// <summary>
        /// deals with drag and drop "*png" and "*.xml" files.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileDrop"))
            {
                try
                {
                    string[] files = (e.Data.GetData("FileDrop") as string[]);

                    if (files.Length == 1 && Path.GetExtension(files[0]) == ".xml")
                    {
                        open(files[0]);
                        updateDataGridView(true, true, true);
                    }

                    else
                    {
                        bool askConfirm = false;
                        DialogResult ds = MessageBox.Show("Ask for override Confirmation?", "Confirmation", MessageBoxButtons.YesNo);
                        if (ds == System.Windows.Forms.DialogResult.Yes)
                        {
                            askConfirm = true;
                        }

                        foreach (string s in files)
                        {
                            NEW_FONT.AddCharacter(s, askConfirm);
                        }
                        updateDataGridView(true, true, true);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }

        }

        private void dataGridViewGlyphs_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }
        /// <summary>
        /// helper method to open editor by double clicking the cell
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                if (!cellSourceDummy())
                    editCharacter();
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// make current cell the cell selected by right mouse button which is usualy ignored.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (dataGridViewGlyphs.SelectedCells.Count <= 1)
                {
                    try
                    {
                        int rowIndex = this.dataGridViewGlyphs.HitTest(e.X, e.Y).RowIndex;
                        int columnIndex = this.dataGridViewGlyphs.HitTest(e.X, e.Y).ColumnIndex;

                        if (rowIndex > -1 && rowIndex < dataGridViewGlyphs.Rows.Count)
                        {
                            if (columnIndex > -1 && columnIndex < dataGridViewGlyphs.Columns.Count)
                            {
                                dataGridViewGlyphs.CurrentCell = this.dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex];
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                    }
                }
            }
        }
        /// <summary>
        /// method to show what dummy image is behind the xml value
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
        {
            if ((dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as CustomDataGridViewCell).DummyImage != null)
                dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as CustomDataGridViewCell).DummyImage;
        }
        /// <summary>
        /// method to show what dummy image is behind the xml value
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
        {
            if ((dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as CustomDataGridViewCell).XmlImage != null)
                dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as CustomDataGridViewCell).XmlImage;
        }
        #endregion

        /// <summary>
        /// menu stip methods, does exactly what the names says and no complicated logic in them.
        /// </summary>
        #region TOOL STRIP MENU'S
        /***************************OPEN, SAVE, CLOSE MENU LISTENERS******************************************/
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                open("");
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                saveFontXML(false);
                MessageBox.Show("Saved!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                saveFontXML(true);
                MessageBox.Show("Saved!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /************************CREATE: EMPTY, FROM FONTSPLITTER, FROM FONT, FROM IMAGES LISTENERS*********************************************/
        private void emptyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                NEW_FONT = new FontFont();
                NEW_FONT.GuessFontValues();
                OLD_DOC_PATH = "";

                this.propertyGrid1.SelectedObject = NEW_FONT;
                GAME.XNA_MAIN_FORM_HELPER.INITIALIZE();
                updateDataGridView(true, true, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void FontSplitterStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                using (tester.Form1 splitter = new Form1())
                {
                    splitter.sendImagesDirectory = new Form1.sendSplitImage(receiveSplitImage);
                    if (splitter.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
                    {
                        OLD_DOC_PATH = "";
                        GAME.XNA_MAIN_FORM_HELPER.INITIALIZE();
                        updateDataGridView(true, true, true);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void fromFontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                using (TTF2PNG t2p = new TTF2PNG())
                {
                    t2p.sendFontDirWithInfo = new TTF2PNG.sendSplitFont(receiveFontDirWithInfo);

                    if (t2p.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
                    {
                        return;
                    }
                    else
                    {
                        OLD_DOC_PATH = "";
                        GAME.XNA_MAIN_FORM_HELPER.INITIALIZE();
                        updateDataGridView(true, true, true);
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void frompngsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                createFontFromImg();
                OLD_DOC_PATH = "";
                if (NEW_FONT != null)
                {
                    GAME.XNA_MAIN_FORM_HELPER.INITIALIZE();
                    updateDataGridView(true, true, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        #endregion

        #region CREATE NEW FONT METHODS
        /// <summary>
        /// receiver method when creating font from existing TTF font.
        /// creates a new FontFont object, guesses its values and then adds characters from given parameters.
        /// The original info of this creation is saved in newFont object.
        /// Datagridview is reinitialized with these new values.
        /// </summary>
        /// <param Name="dir">comes form tt2png</param>
        /// <param Name="fontName">comes form tt2png</param>
        /// <param Name="bold">comes form tt2png</param>
        /// <param Name="italic">comes form tt2png</param>
        /// <param Name="size">comes form tt2png</param>
        /// <param Name="LineColor">comes form tt2png</param>
        private void receiveFontDirWithInfo(string dir, string fontName, bool bold, bool italic, float size, int color)
        {
            try
            {
                NEW_FONT = new FontFont();
                NEW_FONT.GuessFontValues();
                foreach (string link in Directory.GetFiles(dir))
                {
                    if (Path.GetExtension(link) == ".png")
                    {
                        NEW_FONT.AddCharacter(link, true);
                    }
                }
                NEW_FONT.GuessFontValues();
                NEW_FONT.FontOriginName = fontName;
                NEW_FONT.FontOriginBold = bold;
                NEW_FONT.FontOriginItalic = italic;
                NEW_FONT.FontOriginSize = size;
                NEW_FONT.FontOriginColor = color;

                this.propertyGrid1.SelectedObject = NEW_FONT;
                updateDataGridView(true, true, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// takes the directory where fontSplitter saved images and uses them to load new font.
        /// </summary>
        /// <param Name="dir">receives from FontSplitter</param>
        private void receiveSplitImage(string dir)
        {
            try
            {
                NEW_FONT = new FontFont();
                NEW_FONT.GuessFontValues();
                foreach (string link in Directory.GetFiles(dir))
                {
                    NEW_FONT.AddCharacter(link, true);
                }
                updateDataGridView(true, true, true);
                NEW_FONT.GuessFontValues();
                this.propertyGrid1.SelectedObject = NEW_FONT;
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// uses openFileDialog to select multiple object (or single) and uses them to create new font
        /// </summary>
        private void createFontFromImg()
        {
            try
            {
                using (OpenFileDialog OFD = new OpenFileDialog())
                {
                    OFD.Multiselect = true;
                    OFD.Filter = "JPEG .jpeg|*.jpeg;*.jpg|png .png|*.png|All files (*.*)|*.*";
                    OFD.FilterIndex = 2;
                    OFD.Title = "Select image files";

                    if (OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        NEW_FONT = new FontFont();
                        NEW_FONT.GuessFontValues();

                        foreach (string link in OFD.FileNames)
                        {
                            NEW_FONT.AddCharacter(link, true);
                        }
                        NEW_FONT.GuessFontValues();
                        this.propertyGrid1.SelectedObject = NEW_FONT;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// one of the most used methods.
        /// tries to Load font from XML file;
        /// if OLD_DOC_PATH != null ddoes the comparison between folder and charactersList;
        /// deals with missing files in folder, in XML, (info mismatches).
        /// </summary>
        /// <param Name="dir"></param>
        private void open(string dir)
        {
            try
            {
                //Opening from XML and then Init() based on the values;
                loadFontXML(dir);

                if (OLD_DOC_PATH != "")
                {
                    if (Helper.compareFolderWithXML(Path.GetDirectoryName(OLD_DOC_PATH), NEW_FONT).Count > 0)
                    {
                        string msg = "";
                        foreach (string s in Helper.compareFolderWithXML(Path.GetDirectoryName(OLD_DOC_PATH), NEW_FONT))
                            msg += s + "\n";
                        msg += "Files are in folder but not in xml, do you want to include it?";

                        DialogResult d = MessageBox.Show(msg, "Message", MessageBoxButtons.YesNo);
                        if (d == System.Windows.Forms.DialogResult.Yes)
                        {
                            foreach (string s in Helper.compareFolderWithXML(Path.GetDirectoryName(OLD_DOC_PATH), NEW_FONT))
                            {
                                if (Helper.isLinkHexPng(Path.GetDirectoryName(OLD_DOC_PATH) + @"\" + s + ".png"))
                                {
                                    string newPath = Path.GetDirectoryName(OLD_DOC_PATH) + @"\" + s + ".png";
                                    NEW_FONT.AddCharacter(newPath, true);
                                }
                            }
                        }
                    }
                    if (GAME != null)
                    {
                        GAME.XNA_MAIN_FORM_HELPER.INITIALIZE();
                        XNAHelper.REINIT_PREVIEWCHARACTERS = true;
                    }
                    updateDataGridView(true, true, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        #endregion

        #region XML HANDLERS
        /// <summary>
        /// loads xDocument from given XML uri.
        /// returns missingChars is needed info.
        /// </summary>
        /// <param Name="uri"></param>
        private void loadFontXML(string uri)
        {
            try
            {
                XDocument xdoc = new XDocument();
                bool loadFont = false;

                if (uri != "")
                {
                    xdoc = XDocument.Load(uri);
                    OLD_DOC_PATH = uri;
                    loadFont = true;
                }

                else
                {
                    using (OpenFileDialog ofd = new OpenFileDialog())
                    {
                        ofd.Title = "Open XML file";
                        ofd.Filter = "Xml Files (.xml)|*.xml|All Files (*.*)|*.*";
                        ofd.FilterIndex = 0;

                        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            xdoc = XDocument.Load(ofd.FileName);
                            OLD_DOC_PATH = ofd.FileName;  //for saving later purposes
                            loadFont = true;
                            Console.WriteLine(OLD_DOC_PATH);
                        }
                    }
                }

                if (loadFont)
                {
                    OLD_DOC = xdoc;  //for saving later purposes
                    NEW_FONT = new FontFont();
                    NEW_FONT.Name = xdoc.Element("Font").Attribute("Name").Value;
                    NEW_FONT.Space = float.Parse(xdoc.Element("Font").Attribute("Space").Value);
                    NEW_FONT.Kerning = float.Parse(xdoc.Element("Font").Attribute("Kerning").Value);
                    NEW_FONT.Leading = float.Parse(xdoc.Element("Font").Attribute("Leading").Value);
                    NEW_FONT.XHeight = float.Parse(xdoc.Element("Font").Attribute("XHeight").Value);
                    NEW_FONT.CapHeight = float.Parse(xdoc.Element("Font").Attribute("CapHeight").Value);
                    NEW_FONT.AscenderHeight = float.Parse(xdoc.Element("Font").Attribute("AscenderHeight").Value);
                    NEW_FONT.DescenderHeight = float.Parse(xdoc.Element("Font").Attribute("DescenderHeight").Value);

                    NEW_FONT.FontOriginName = xdoc.Element("Font").Attribute("FontOriginName").Value;
                    NEW_FONT.FontOriginBold = bool.Parse(xdoc.Element("Font").Attribute("FontOriginBold").Value);
                    NEW_FONT.FontOriginItalic = bool.Parse(xdoc.Element("Font").Attribute("FontOriginItalic").Value);
                    NEW_FONT.FontOriginSize = float.Parse(xdoc.Element("Font").Attribute("FontOriginSize").Value);
                    NEW_FONT.FontOriginColor = int.Parse(xdoc.Element("Font").Attribute("FontOriginColor").Value);

                    string missingChars = "";
                    foreach (XElement child in xdoc.Element("Font").Elements())
                    {
                        if (File.Exists(Path.GetDirectoryName(OLD_DOC_PATH) + @"\" + child.Attribute("unicode").Value + ".png"))
                        {
                            FontCharacter c = new FontCharacter(child.Attribute("unicode").Value,
                                    float.Parse(child.Attribute("anchorPointX").Value),
                                    float.Parse(child.Attribute("anchorPointY").Value),
                                    float.Parse(child.Attribute("width").Value));

                            c.Image = Path.GetDirectoryName(OLD_DOC_PATH) + @"\" + c.Name + ".png"; //taking xml file directory and adding to it file names; 
                            c.GuessOnlyHeight();
                            NEW_FONT.Characters.Add(c);
                        }
                        else
                        {
                            missingChars += "\n" + (string.Format("HEX '{0}' exists in XML but is not in the folder.", child.Attribute("unicode").Value));
                        }
                    }
                    if (missingChars != "")
                        using (MissingChar ms = new MissingChar(missingChars))
                        {
                            ms.ShowDialog();
                        }


                    this.propertyGrid1.SelectedObject = NEW_FONT;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// creates an xDocument file from current font object.
        /// </summary>
        /// <returns>xDocument with FontFont info in it</returns>
        private XDocument createFontXML()
        {
            XDocument xdoc = new XDocument(
                new XElement("Font",
                    new XAttribute("Name", NEW_FONT.Name),
                    new XAttribute("Space", NEW_FONT.Space),
                    new XAttribute("Kerning", NEW_FONT.Kerning),
                    new XAttribute("Leading", NEW_FONT.Leading),
                    new XAttribute("XHeight", NEW_FONT.XHeight),
                    new XAttribute("CapHeight", NEW_FONT.CapHeight),
                    new XAttribute("AscenderHeight", NEW_FONT.AscenderHeight),
                    new XAttribute("DescenderHeight", NEW_FONT.DescenderHeight),

                    new XAttribute("FontOriginName", NEW_FONT.FontOriginName),
                    new XAttribute("FontOriginBold", NEW_FONT.FontOriginBold),
                    new XAttribute("FontOriginItalic", NEW_FONT.FontOriginItalic),
                    new XAttribute("FontOriginSize", NEW_FONT.FontOriginSize),
                    new XAttribute("FontOriginColor", NEW_FONT.FontOriginColor),

                    NEW_FONT.Characters.Select(item =>
                        new XElement("Character",
                        new XAttribute("unicode", item.Name),
                        new XAttribute("anchorPointX", item.AnchorPoint.X),
                        new XAttribute("anchorPointY", item.AnchorPoint.Y),
                        new XAttribute("width", item.Width)))));

            return xdoc;
        }

        ///No longer used method which was used for updating XML file at runtime
        //private void UpdateFontXML(string Element, string ElementChild, string attribute, object value)
        //{
        //    oldDoc.Element(Element).Attribute(attribute).SetValue(value);
        //    if (ElementChild != "")
        //        oldDoc.Element(Element).Element(ElementChild).Attribute(attribute).SetValue(value);
        //}

        /// <summary>
        /// since XML stores only textual information instead of updating it I am just recreating it and overwriting it.
        /// two checks are done to determine if saveFileDialog is needed. 
        /// in the end copyPNGToFolder() method is invoked if needed.
        /// </summary>
        /// <param Name="saveAs">when true opens "save file dialog" even though it the file was loaded from somewhere</param>
        private void saveFontXML(bool saveAs)
        {
            try
            {
                OLD_DOC = createFontXML();

                if (saveAs || OLD_DOC_PATH == "")
                {
                    using (SaveFileDialog sfd = new SaveFileDialog())
                    {
                        string tempPath = "";
                        sfd.Title = "Save XML file";
                        sfd.Filter = "Xml Files (.xml)|*.xml|All Files (*.*)|*.*";
                        sfd.FilterIndex = 0;

                        if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            tempPath = Path.GetDirectoryName(sfd.FileName);
                            OLD_DOC.Save(sfd.FileName);
                        }
                        copyPNGToFolder(tempPath);
                    }
                }
                else
                {
                    copyPNGToFolder(Path.GetDirectoryName(OLD_DOC_PATH));
                    OLD_DOC.Save(OLD_DOC_PATH);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// deals with the cases when image is loaded not from original xml file folder.
        /// </summary>
        /// <param Name="tempPath"></param>
        private void copyPNGToFolder(string tempPath)
        {
            try
            {
                bool filesNeedCopying = false;

                foreach (FontCharacter c in NEW_FONT.Characters)
                {
                    string tempLink = tempPath + @"\" + c.Name + ".png";
                    if (!File.Exists(tempLink) || tempLink != c.Image)
                    {
                        filesNeedCopying = true;
                        break;
                    }
                }

                if (filesNeedCopying)
                {
                    DialogResult m = Helper.infoBox("Copy files which doesn't exist in XML folder to it?", "Confirmation");
                    if (m == System.Windows.Forms.DialogResult.Yes)
                    {
                        foreach (FontCharacter c in NEW_FONT.Characters)
                        {
                            string tempLink = tempPath + @"\" + c.Name + ".png";
                            if (!File.Exists(tempLink) || tempLink != c.Image)
                            {
                                File.Copy(c.Image, tempPath + @"\" + c.Name + ".png", true);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        ///No longer used. Was used for deleting the images from the directory which were not a part of the font.
        //private void cleanDirectoryImages(string tempPath)
        //{

        //    string[] dirpngs = Directory.GetFiles(tempPath);
        //    Console.WriteLine("tempPath\t" + tempPath);

        //    foreach (string s in dirpngs)
        //    {
        //        Console.WriteLine("s\t"+s);
        //        Console.WriteLine(s);
        //        if (!newFont.ContainsCharImgUri(s))
        //            File.Delete(s);
        //    }
        //}
        /// <summary>
        /// loads filters from XML to FILTER_SET dictionary
        /// </summary>
        private void loadFilterXML()
        {
            try
            {
                XDocument xdoc = XDocument.Load(FILTER_URI);

                foreach (XElement flter in xdoc.Element("Filters").Elements())
                {
                    Filter filter = new Filter(
                    flter.Attribute("Name").Value,
                    flter.Attribute("Characters").Value);
                    FILTER_SET.Add(filter.Name, filter);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// loads dummies to DUMMY_SET dictionary
        /// </summary>
        private void loadDummyXML()
        {
            try
            {
                XDocument xdoc = XDocument.Load(DUMMY_SET_URI);

                foreach (XElement dummy in xdoc.Element("DummySets").Elements())
                {
                    DummySet ds = new DummySet(
                    dummy.Attribute("Name").Value,
                    dummy.Element("Characters").Value);
                    DUMMY_SET.Add(dummy.Attribute("Name").Value, ds);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        #endregion

        #region DRAG DROP XML
        /// <summary>
        /// allows to just drag and drop xml file and it will load it.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void FontToolMain_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileDrop"))
            {
                try
                {
                    string[] files = (e.Data.GetData("FileDrop") as string[]);

                    if (files.Length == 1 && Path.GetExtension(files[0]) == ".xml")
                    {
                        open(files[0]);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }

        private void FontToolMain_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }
        #endregion

        #region PREVIEW CONTEXT MENU
        private void updateZoom(float zoom)
        {
            try
            {
                previewContextMenu.Visible = false;
                GAME.XNA_MAIN_FORM_HELPER.PREVIEW_CAMERA.Zoom = zoom;
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// clicked item passes _zoom value which will be applied as preview drawing scale.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        void previewContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "25%":
                    updateZoom(.25f);
                    break;
                case "50%":
                    updateZoom(.5f);
                    break;
                case "75%":
                    updateZoom(.75f);
                    break;
                case "100%":
                    updateZoom(1f);
                    break;
                case "125%":
                    updateZoom(1.25f);
                    break;
                case "150%":
                    updateZoom(1.5f);
                    break;
                case "175%":
                    updateZoom(1.75f);
                    break;
                case "200%":
                    updateZoom(2f);
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region GRID VIEW CONTEXT MENU
        /// <summary>
        /// will deal with what can happen when right clicked cell
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        void gridViewContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "Add...":
                    gridViewContextMenu.Visible = false;
                    addCharacter();
                    break;
                case "Add origin...":
                    gridViewContextMenu.Visible = false;
                    AddOriginfontCharacter();
                    break;
                case "Replace...":
                    gridViewContextMenu.Visible = false;
                    replaceCharacter();
                    break;
                case "Remove...":
                    gridViewContextMenu.Visible = false;
                    removeCharacter();
                    break;
                case "Edit...":
                    gridViewContextMenu.Visible = false;
                    editCharacter();
                    break;
                case "Open in Editor...":
                    gridViewContextMenu.Visible = false;
                    openInEditorCharacter();
                    break;
                default:
                    gridViewContextMenu.Visible = false;
                    break;
            }
        }
        /// <summary>
        /// adds a character to font character list.
        /// </summary>
        private void addCharacter()
        {
            try
            {
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.Multiselect = true;

                    if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        foreach (string s in ofd.FileNames)
                        {
                            NEW_FONT.AddCharacter(s, true);
                        }
                        updateDataGridView(false, true, false);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// if currect cell is not null or empty replaces selected cell with new image using NEW_FONT.ReplaceCharacter(old,new);
        /// </summary>
        private void replaceCharacter()
        {
            try
            {
                if (dataGridViewGlyphs.CurrentCell.Value != null || dataGridViewGlyphs.CurrentCell.ToolTipText != "")
                {
                    using (OpenFileDialog ofd = new OpenFileDialog())
                    {
                        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            NEW_FONT.ReplaceCharacter(dataGridViewGlyphs.CurrentCell.ToolTipText, NEW_FONT.CreateCharacter(ofd.FileName), true);
                            updateDataGridView(true, true, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        /// <summary>
        /// removes the character from font BUT doesn't delete it from the system.
        /// </summary>
        private void removeCharacter()
        {
            try
            {
                DialogResult ds = MessageBox.Show("Delete all selected character?", "Confirm delete", MessageBoxButtons.YesNoCancel);

                if (ds == System.Windows.Forms.DialogResult.Yes)
                {
                    foreach (CustomDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                    {
                        if (s.ToolTipText != "")
                        {
                            NEW_FONT.DeleteCharacter(s.ToolTipText);
                        }
                    }
                    updateDataGridView(true, true, true);

                }

                if (ds == System.Windows.Forms.DialogResult.No)
                {
                    foreach (CustomDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                    {
                        if (s.GetCellSource == CustomDataGridViewCell.CellSource.XML)
                            if (MessageBox.Show("Delete character '" + s.ToolTipText + "'", "Confirm delete", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                            {
                                NEW_FONT.DeleteCharacter(s.ToolTipText);
                            }
                    }
                    updateDataGridView(true, true, true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// works for single or multiple cells at once.
        /// creates customTabPage and inits all its methods;
        /// sets it as a currect property grid object.
        /// </summary>
        private void editCharacter()
        {
            try
            {
                foreach (CustomDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                {
                    if (s.GetCellSource == CustomDataGridViewCell.CellSource.XML)
                    {
                        if (!tabControlContainsPage(s.ToolTipText))
                        {
                            CustomTabPage tempPage = new CustomTabPage(s.ToolTipText);
                            tempPage.RefreshRequest = new CustomTabPage.sendRefreshRequest(() =>
                            {
                                propertyGrid1.Refresh();
                                XNAHelper.REINIT_PREVIEWCHARACTERS = true;
                            });

                            this.tabControl1.Controls.Add(tempPage);
                            tabControl1.SelectedTab = tempPage;
                            tempPage.ContextMenuStrip = this.tabControlContextMenu;
                            //handles update of propertyGrid selectedObject when clicked.
                            tempPage.TabPictureBox.MouseClick += new MouseEventHandler((o, sw) =>
                            {
                                propertyGrid1.SelectedObject = NEW_FONT.GetCharacter(tabControl1.SelectedTab.Text);
                            });
                        }
                        this.propertyGrid1.SelectedObject = NEW_FONT.GetCharacter(s.ToolTipText);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private bool tabControlContainsPage(string name)
        {
            bool contains = false;
            foreach (CustomTabPage t in tabControl1.TabPages)
            {
                if (t.Name == name)
                {
                    contains = true;
                    tabControl1.SelectedTab = t;
                    break;
                }
            }
            return contains;
        }
        /// <summary>
        /// opens openWidth dialog to select with which program you wanna edit file.
        /// </summary>
        private void openInEditorCharacter()
        {
            try
            {
                foreach (CustomDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                {
                    if (s.GetCellSource == CustomDataGridViewCell.CellSource.XML)
                    {
                        this.Invoke(new MethodInvoker(() =>
                        {
                            Process p = new Process();
                            ProcessStartInfo startInfo = new ProcessStartInfo("rundll32.exe");
                            startInfo.UseShellExecute = false;
                            startInfo.RedirectStandardOutput = true;
                            startInfo.Arguments = "shell32.dll ,OpenAs_RunDLL " + NEW_FONT.GetCharacter(s.ToolTipText).Image;
                            p.StartInfo = startInfo;
                            p.Start();
                        }));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        /// pass string with char's which you wanna generate;
        /// by using original font properties saved on creation time creates wanted characters;
        /// 
        /// </summary>
        private void AddOriginfontCharacter()
        {
            try
            {
                string missingChars = string.Empty;
                string extractDir = string.Empty;
                DialogResult dr = Helper.InputBox("Add origin character", "Insert character: ", getSelectedCellChar(), ref missingChars);
                if (dr == System.Windows.Forms.DialogResult.OK)
                {
                    using (TTF2PNG t2p = new TTF2PNG())
                    {
                        t2p.sendFontDir = new TTF2PNG.sendSaveDir((o) => { extractDir = o; });
                        t2p.FontName.Text = NEW_FONT.FontOriginName;
                        t2p.FontStyle.Text = getFontStyle();
                        t2p.FontSize.Text = NEW_FONT.FontOriginSize.ToString();
                        t2p.Sample.ForeColor = Color.FromArgb(NEW_FONT.FontOriginColor);
                        t2p.checkBoxNUMBERS.Checked = false;
                        t2p.checkBoxUPPERCASE.Checked = false;
                        t2p.checkBoxLOWERCASE.Checked = false;
                        t2p.checkBoxSPECIAL.Checked = false;
                        t2p.checkBoxSYMBOLS.Checked = false;
                        t2p.checkBoxpng.Checked = false;
                        t2p.textBox1.Text = missingChars;
                        t2p.Export_Click(null, null);
                    }

                    foreach (char c in missingChars)
                    {
                        string tempUri = Path.Combine(extractDir, Helper.charToHex(c) + ".png");
                        Console.WriteLine(tempUri);
                        NEW_FONT.AddCharacter(tempUri, true);
                    }
                    updateDataGridView(true, true, false);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns>returns the string with all selected cells 'char' values</returns>
        private string getSelectedCellChar()
        {
            string msg = string.Empty;
            foreach (CustomDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
            {
                msg += Helper.HEXtoCHAR(s.ToolTipText);
            }
            return msg;
        }
        /// <summary>
        /// helper method to deal with original font parameters
        /// </summary>
        /// <returns></returns>
        private string getFontStyle()
        {
            string msg = "Regular";
            if (NEW_FONT.FontOriginBold)
                msg = "Bold";
            if (NEW_FONT.FontOriginItalic)
                msg = "Italic";
            if (NEW_FONT.FontOriginBold && NEW_FONT.FontOriginItalic)
                msg = "Bold, Italic";
            return msg;
        }
        #endregion

        #region ZOOM GRID CONTEXT MENU
        /// <summary>
        /// based on clickedItem changes cells size;
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void zoomGridContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            try
            {
                switch (e.ClickedItem.Text)
                {
                    case "25%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (25 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "25%";
                        break;
                    case "50%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (50 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "50%";
                        break;
                    case "75%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (75 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "75%";
                        break;
                    case "100%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (100 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "100%";
                        break;
                    case "125%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (125 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "125%";
                        break;
                    case "150%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (150 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "150%";
                        break;
                    case "175%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (175 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "175%";
                        break;
                    case "200%":
                        zoomContextMenu.Visible = false;
                        CELL_WIDTH = (200 * CELL_ORIGIN_WIDTH) / 100;
                        updateDataGridView(true, true, false);
                        labelGridScale.Text = "200%";
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }
        #endregion

        #region BUTTONS CLICK
        private void buttonGridZoomIn_Click(object sender, EventArgs e)
        {
            try
            {
                CELL_WIDTH += 2;
                updateDataGridView(true, true, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void buttonGridZoomOut_Click(object sender, EventArgs e)
        {
            try
            {
                CELL_WIDTH -= 2;
                updateDataGridView(true, true, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
        }

        private void buttonGridZoomOrigin_Click(object sender, EventArgs e)
        {
            try
            {
                CELL_WIDTH = CELL_ORIGIN_WIDTH;
                updateDataGridView(true, true, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
            }
            ///testing part of code:
            ///check to determine if there are two items with the same character
            //foreach (FontCharacter c in NEW_FONT.Characters)
            //{
            //    string currentName = c.Name;
            //    int namesRepeat = 0;
            //    foreach (FontCharacter h in NEW_FONT.Characters)
            //    {
            //        if (h.Name == currentName)
            //        {
            //            namesRepeat++;
            //            Console.WriteLine(h.Name + ":" + namesRepeat);
            //        }
            //    }
            //    namesRepeat = 0;
            //}
        }

        private void buttonPreviewMaximize_Click(object sender, EventArgs e)
        {
            splitContainer2.Panel1Collapsed = !splitContainer2.Panel1Collapsed;
        }

        private void buttonPreviewZoom_Click(object sender, EventArgs e)
        {
            if (NEW_FONT != null)
            {
                try
                {
                    //returns _zoom to 100%
                    GAME.XNA_MAIN_FORM_HELPER.PREVIEW_CAMERA.Zoom = 1f;
                    XNAHelper.REINIT_PREVIEWCHARACTERS = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }

        bool DRAW_ALL_LINES = true;
        private void buttonPreviewLines_Click(object sender, EventArgs e)
        {
            if (NEW_FONT != null)
            {
                try
                {
                    DRAW_ALL_LINES = !DRAW_ALL_LINES;
                    NEW_FONT.drawAllLines(DRAW_ALL_LINES);
                    propertyGrid1.Refresh();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }

        private void buttonPreviewBackground_Click(object sender, EventArgs e)
        {
            if (NEW_FONT != null)
            {
                try
                {
                    using (OpenFileDialog ofd = new OpenFileDialog())
                    {
                        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            GAME.initPreviewBackground(ofd.FileName);
                            NEW_FONT.UseBackground = true;
                            NEW_FONT.UseTileBackground = false;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }

        private void buttonPreviewTiles_Click(object sender, EventArgs e)
        {
            if (NEW_FONT != null)
            {
                try
                {
                    using (OpenFileDialog ofd = new OpenFileDialog())
                    {
                        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            GAME.initPreviewTiles(ofd.FileName);
                            NEW_FONT.UseBackground = false;
                            NEW_FONT.UseTileBackground = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }
        #endregion

        #region RESIZE, CLOSE, TEXTBOX METHODS
        private void mainform_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void mainform_Resize(object sender, EventArgs e)
        {
            updateDataGridView(true, true, true);
        }

        private void textBoxSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (NEW_FONT != null)
            {
                try
                {
                    if (e.KeyChar == (char)Keys.Enter)
                    {
                        bool contains = false;
                        //search for character value
                        if (textBoxSearch.Text.StartsWith("0x"))
                        {
                            if (NEW_FONT.ContainsCharHEX(textBoxSearch.Text))
                                contains = true;
                        }
                        //search for char value
                        if (textBoxSearch.Text.Length == 1)
                        {
                            if (NEW_FONT.ContainsCharCHARACTER(textBoxSearch.Text[0]))
                            {
                                contains = true;
                                textBoxSearch.Text = Helper.charToHex(textBoxSearch.Text[0]);
                            }
                        }
                        //finding value in grid.
                        if (contains)
                        {
                            foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                                foreach (CustomDataGridViewCell cell in row.Cells)
                                    if (cell.ToolTipText == textBoxSearch.Text)
                                    {
                                        dataGridViewGlyphs.CurrentCell = cell;
                                        (tabControl1.TabPages[tabControl1.SelectedIndex] as CustomTabPage).Initialize(dataGridViewGlyphs.CurrentCell.ToolTipText);
                                        propertyGrid1.SelectedObject = NEW_FONT.GetCharacter(tabControl1.SelectedTab.Text);
                                    }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("error occured in MainForm class. \n" + ex.Message);
                }
            }
        }
        #endregion

        #region INITIALZIATION METHODS
        /// <summary>
        /// tooltip Initialize method. (messages which shows up when the mouse stays stationed over control for a while.)
        /// </summary>
        private void initTooltips()
        {
            ToolTip TT = new ToolTip();
            TT.SetToolTip(buttonPreviewMaximize, "maximize the screen");
            TT.SetToolTip(buttonPreviewZoom, "set preview to default");
            TT.SetToolTip(buttonPreviewLines, @"Show\Hide lines");
            TT.SetToolTip(buttonPreviewBackground, "set background image");

            TT.SetToolTip(buttonGridZoomOut, "_zoom grid OUT");
            TT.SetToolTip(buttonGridZoomIn, "_zoom grid IN");
            TT.SetToolTip(buttonGridZoomOrigin, "set grid to default");

            TT.SetToolTip(textBoxSearch, "enter HEX value and press ENTER");
            TT.SetToolTip(checkBoxDummy, "Use dummy char set?");
            TT.SetToolTip(comboBoxDummySets, "select dummy set..");
            TT.SetToolTip(comboBoxFilter, "select filter...");
            TT.SetToolTip(buttonPreviewTiles, "Load background from tiles");
            TT.SetToolTip(numericUpDown1, "Lines transparency percent");
        }

        /// <summary>
        /// Inits context menu based on list at the top.
        /// Connects contextMenu with its itemClicked events.
        /// </summary>
        private void initContextMenus()
        {

            gridViewContextMenu.Items.Clear();
            for (int i = 0; i < GLYPH_MENU.Length; i++)
                gridViewContextMenu.Items.Add(GLYPH_MENU[i]);
            gridViewContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(gridViewContextMenu_ItemClicked);

            zoomContextMenu.Items.Clear();
            for (int i = 0; i < ZOOM_MENU.Length; i++)
                zoomContextMenu.Items.Add(ZOOM_MENU[i]);
            zoomContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(zoomGridContextMenu_ItemClicked);

            previewContextMenu.Items.Clear();
            for (int i = 0; i < ZOOM_MENU.Length; i++)
                previewContextMenu.Items.Add(ZOOM_MENU[i]);
            previewContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(previewContextMenu_ItemClicked);

            tabControlContextMenu.Items.Clear();
            for (int i = 0; i < TAB_MENU.Length; i++)
                tabControlContextMenu.Items.Add(TAB_MENU[i]);
            tabControlContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(tabControlContextMenu_ItemClicked);
        }

        /// <summary>
        /// Alters selected tabPage (character window at the top right) _zoom variables
        /// and causes it to scale or shrink.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        void tabControlContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "25%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 0.25f;
                    break;
                case "50%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 0.5f;
                    break;
                case "75%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 0.75f;
                    break;
                case "100%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 1f;
                    break;
                case "125%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 1.25f;
                    break;
                case "150%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 1.5f;
                    break;
                case "175%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 1.75f;
                    break;
                case "200%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 2f;
                    break;
                case "400%":
                    (tabControl1.SelectedTab as CustomTabPage).Zoom = 4f;
                    break;
                case "Close":
                    tabControl1.TabPages.Remove(tabControl1.SelectedTab);
                    break;
                case "Close All":
                    tabControl1.TabPages.Clear();
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Takes texture2d loaded in XNA content and after its transformed into image
        /// assigns it as buttons background images.
        /// </summary>
        public void initButtonImages()
        {
            buttonPreviewBackground.BackgroundImage = Helper.Texture2Image(GAME.ICON_BACKGROUND);
            buttonPreviewLines.BackgroundImage = Helper.Texture2Image(GAME.ICON_LINES);
            buttonPreviewMaximize.BackgroundImage = Helper.Texture2Image(GAME.ICON_MAXIMIZE);
            buttonPreviewTiles.BackgroundImage = Helper.Texture2Image(GAME.ICON_TILES);
            buttonPreviewZoom.BackgroundImage = Helper.Texture2Image(GAME.ICON_ZOOM_ORIGIN);

            buttonGridZoomIn.BackgroundImage = Helper.Texture2Image(GAME.ICON_ZOOM_IN);
            buttonGridZoomOrigin.BackgroundImage = Helper.Texture2Image(GAME.ICON_ZOOM_ORIGIN);
            buttonGridZoomOut.BackgroundImage = Helper.Texture2Image(GAME.ICON_ZOOM_OUT);
        }
        #endregion
        /// <summary>
        /// changes propertygrid focused object
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void panelPreview_Click(object sender, EventArgs e)
        {
            propertyGrid1.SelectedObject = NEW_FONT;
        }

        /// <summary>
        /// changes propertygrid focused object
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void panelPreview_Click(object sender, MouseEventArgs e)
        {
            propertyGrid1.SelectedObject = NEW_FONT;
        }

        /// <summary>
        /// changes propertygrid focused object
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedTab != null)
                propertyGrid1.SelectedObject = NEW_FONT.GetCharacter(tabControl1.SelectedTab.Text);
            else
                propertyGrid1.SelectedObject = NEW_FONT;
        }
        /// <summary>
        /// updates all tab pages once the values ir property grid changes.
        /// </summary>
        /// <param Name="s"></param>
        /// <param Name="e"></param>
        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            foreach (CustomTabPage tab in tabControl1.TabPages)
            {
                tab.ReInitialize();
            }
            propertyGrid1.Refresh();
            XNAHelper.REINIT_PREVIEWCHARACTERS = true;
        }
        /// <summary>
        /// for simplicity. 
        /// by clicking caused clear textbox field makes it more friendly to use search.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void textBoxSearch_MouseClick(object sender, MouseEventArgs e)
        {
            textBoxSearch.Text = "";
        }
        /// <summary>
        /// deals with the case when instead of opening new tab whenever you click on the cell it re-initializes it
        /// based on selected cell properties (calls customTabPage.Initialize(character) method.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void dataGridViewGlyphs_SelectionChanged(object sender, EventArgs e)
        {
            if (dataGridViewGlyphs.CurrentCell.ToolTipText != "")
            {
                if (!this.cellSourceDummy())
                {
                    if (tabControl1.TabPages.Count > 0)
                    {
                        (tabControl1.TabPages[tabControl1.SelectedIndex] as CustomTabPage).Initialize(dataGridViewGlyphs.CurrentCell.ToolTipText);
                        propertyGrid1.SelectedObject = NEW_FONT.GetCharacter(tabControl1.SelectedTab.Text);
                    }
                    else
                        editCharacter();
                }
            }
        }

        /// <summary>
        /// method to alter Alpha value in XNAHelper from where value is taken when drawing lines
        /// in both previews.
        /// </summary>
        /// <param Name="sender"></param>
        /// <param Name="e"></param>
        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            XNAHelper.Alpha = (float)(numericUpDown1.Value / 100);
        }

    }
}
